#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM_THREADS	8
#define N 1000000000

/**

metodo que sera utilizado pelas thredas que ira calcular um ponto(x, y) randomicamente
e calculara a distancia desse ponto a origem, com isso dizendo se o ponto estara 
dentro ou fora do circulo, e retorna quantos pontos estavam dentro do circulo
com isso auxiliando para calcular o valor da constante pi pelo metodo de monte carlo

*/

void *calcPoint(void *t)
{   
	long int i;
   double x, y;

	//para gerar os numeros aleatorios
	struct drand48_data randBuffer;
	srand48_r(time(NULL), &randBuffer);
	long int c = 0;
   long int n = N/NUM_THREADS;

	for(i = 0; i < n; i++)
	{
		drand48_r(&randBuffer, &x);
		drand48_r(&randBuffer, &y);
		if(sqrt(x*x + y*y) <= 1)
		{
			c++;								
		}
	}

   pthread_exit((void*) c);
}

int main (int argc, char *argv[])
{                  
	//declarando o vetor de thread
   pthread_t thread[NUM_THREADS];
   int rc;
   long t, v;
	int c = 0;
   void *aux;   

	//criando as threads
	for(t = 0; t < NUM_THREADS; t++)
	{
      rc = pthread_create(&thread[t], NULL, calcPoint, (void*) t); 
		/*entra caso a thread obteve algum erro
		  caso a execucao teve sucesso retorna 0
		*/
      if (rc)
		{
         printf("ERRO! codigo de retorno da pthread_create(): %d\n", rc);
         exit(-1);

		}
	}

   /*
	  esperando pelas outras threads e pegando a qtde
     de pontos que estavam dentro da circunferencia
	*/
   for(t = 0; t<NUM_THREADS; t++)
	{
      rc = pthread_join(thread[t], &aux);
      if (rc)
		{
         printf("ERRO! codigo de retorno da pthread_join() : %d\n", rc);
         exit(-1);      
		} 	

		c += (long)aux;     
	} 	

	//printando o valor aproximado da constante pi
	printf("%.6f\n", 4*((float)c/(float)N));
	
	pthread_exit(NULL);
}


